package com.wangshb.upms.generate;

import com.wangshb.upms.generate.generate.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.apache.ibatis.type.TypeReference;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class GenerateUtil {


    /**
     * 获取jdbc链接
     * @param url
     * @param username
     * @param password
     * @return
     * @throws Exception
     */
    public static Connection getConnection(String url, String username, String password) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        return DriverManager.getConnection(url,username,password);
    }


    public static List<TableEntity> getTableEntityList(String url, String username, String password, String tableNamePattern) throws Exception {
        Connection connection = getConnection(url, username, password);
        DatabaseMetaData metaData = connection.getMetaData();
        ResultSet tables = metaData.getTables(null, null, tableNamePattern, new String[]{"TABLE"});
        List<TableEntity> list = new ArrayList<>();

        TypeHandlerRegistry registry = new TypeHandlerRegistry();
        while (tables.next()) {
            String table_name = tables.getString("TABLE_NAME");
            String remarks = tables.getString("REMARKS");

            TableEntity tableEntity = new TableEntity();
            tableEntity.setTableName(table_name);
            tableEntity.setEntityName(replaceUnderLineAndUpperCase(table_name, false));
            tableEntity.setAliasName(replaceUnderLineAndUpperCase(table_name, true));
            tableEntity.setDescription(remarks);

            ResultSet primaryKeyResultSet = metaData.getPrimaryKeys(null, null, table_name);
            String primaryKey = "";
            if (primaryKeyResultSet.next()) {
                primaryKey = primaryKeyResultSet.getString("COLUMN_NAME");
            }


            ArrayList<ColumnProperty> columnProperties = new ArrayList<>();
            ResultSet columns = metaData.getColumns(null, null, table_name, null);
            while(columns.next()){
                String column_name = columns.getString("COLUMN_NAME");
                ColumnProperty columnProperty = new ColumnProperty();
                columnProperty.setColumnName(column_name);
                columnProperty.setPropertyName(replaceUnderLineAndUpperCase(column_name,true));
                columnProperty.setDescription(columns.getString("REMARKS"));
                String data_type = columns.getString("data_type");
                String type_name = columns.getString("TYPE_NAME");

                if (type_name.equalsIgnoreCase("DATETIME")) {
                    columnProperty.setColumnType("TIMESTAMP");
                }
                else if (type_name.equalsIgnoreCase("INT")) {
                    columnProperty.setColumnType("INTEGER");
                } else {
                    columnProperty.setColumnType(type_name);
                }

                JdbcType jdbcType = JdbcType.forCode(Integer.valueOf(data_type));
                TypeReference typeHandler = (TypeReference) registry.getTypeHandler(jdbcType);
                String typeName = typeHandler.getRawType().getTypeName();
                if (typeName.contains("java.lang.")) {
                    columnProperty.setJavaType(typeName.substring(typeName.lastIndexOf(".") + 1));
                }
                else {
                    columnProperty.setJavaType(typeName);
                }

                if(column_name.equalsIgnoreCase(primaryKey)) {
                    tableEntity.setKeyColumnProperty(columnProperty);
                }
                else {
                    columnProperties.add(columnProperty);
                }
            }

            tableEntity.setColumnPropertyList(columnProperties);
            list.add(tableEntity);
        }
        return list;
    }


    public static String replaceUnderLineAndUpperCase(String str, boolean ignoreFirstChar){
        StringBuffer sb = new StringBuffer();
        sb.append(str);
        int count = sb.indexOf("_");
        while(count!=0){
            int num = sb.indexOf("_",count);
            count = num + 1;
            if(num != -1){
                char ss = sb.charAt(count);
                char ia;
                ia = (char) (ss - 32);
                sb.replace(count , count + 1,ia + "");
            }
        }
        String result = sb.toString().replaceAll("_","");
        return ignoreFirstChar ? result : StringUtils.capitalize(result);
    }


    public static void main(String[] args) throws Exception {
        String url = "jdbc:mysql://localhost:3306/upms?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&useSSL=false";
        String username = "root";
        String password = "123456";

        List<TableEntity> tableEntityList = getTableEntityList(url, username, password, "upms_role");
        Configuration configuration = new Configuration();
        configuration.setJavaSrcPath("D:\\wangshb\\code\\upms\\src\\main\\java");
        configuration.setJsSrcPath("D:\\wangshb\\code\\vue-admin-template\\src");
        configuration.setPackageName("com.wangshb.upms");
        configuration.setVersionColumn("version");
        configuration.setTableEntity(tableEntityList.get(0));
        configuration.setSearchColumnList(new ArrayList<String>(){
            {
                this.add("role_name");
                this.add("role_code");
            }
        });
        new EntityGenerate(configuration).generate();
        new MapperGenerate(configuration).generate();
        new DaoGenerate(configuration).generate();

        new ServiceGenerate(configuration).generate();
        new ServiceImplGenerate(configuration).generate();

        new ControllerGenerate(configuration).generate();
        new AddRequestDtoGenerate(configuration).generate();
        new EditRequestDtoGenerate(configuration).generate();
        new GetRequestDtoGenerate(configuration).generate();
        new GetResponseDtoGenerate(configuration).generate();
        new QueryRequestDtoGenerate(configuration).generate();
        new QueryResponseDtoGenerate(configuration).generate();
        new DelRequestDtoGenerate(configuration).generate();

        new JsGenerate(configuration).generate();
        new VueGenerate(configuration).generate();
    }
}
